package menu

import (
	"context"
	"git.mycaigou.com/gfyx/common/usermetadata"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/errcode"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/dto/base"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/menu"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/permission"
	userRepo "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
)

type menuService struct {
	menuRepo       menu.MenuRepositoryIface
	permissionRepo permission.PermissionRepositoryIface
	userRepo       userRepo.UserRepositoryIface
}

// NewMenuService 构造展示
func NewMenuService(
	menuRepo menu.MenuRepositoryIface,
	permissionRepo permission.PermissionRepositoryIface,
	userRepo userRepo.UserRepositoryIface,
) MenuServiceIface {
	return &menuService{
		menuRepo:       menuRepo,
		permissionRepo: permissionRepo,
		userRepo:       userRepo,
	}
}

// MenuConfig 菜单列表
func (s *menuService) MenuConfig(ctx context.Context, onlyCurrentUser int64) ([]*base.MenuConfig, error) {
	var menuIds = make([]int64, 0)
	metaUserInfo := usermetadata.GetMetaUserInfo(ctx)
	list, err := s.menuRepo.MenuList(ctx)
	if err != nil {
		return nil, err
	}

	// 获取用户信息
	userInfo, err := s.userRepo.UserDetailByUserId(ctx, metaUserInfo.UserId)
	if err != nil {
		return nil, err
	} else if userInfo == nil || userInfo.Id == 0 {
		return nil, errcode.UserNotExist
	}

	// 如果不是超级管理员，则获取用户菜单权限
	if onlyCurrentUser == 1 && userInfo.IsAdmin == 0 {
		// 通过用户id获取菜单权限id
		permissionList, err := s.permissionRepo.GetPermissionByUserId(ctx, metaUserInfo.UserId)
		if err != nil {
			return nil, err
		}
		for _, item := range permissionList {
			menuIds = append(menuIds, item.GfyxMenuId)
		}
	} else {
		for _, mItem := range list {
			menuIds = append(menuIds, mItem.Id)
		}
	}

	permissionList, err := s.permissionRepo.PermissionListByMenuIds(ctx, menuIds)
	if err != nil {
		return nil, err
	}

	permissionListMap := make(map[int64][]*permission.GfyxPermission)
	for _, pItem := range permissionList {
		pList, ok := permissionListMap[pItem.GfyxMenuId]
		if !ok {
			pList = make([]*permission.GfyxPermission, 0)
		}
		pList = append(pList, pItem)
		permissionListMap[pItem.GfyxMenuId] = pList
	}

	menuList2Map := make(map[int64]*menu.GfyxMenuPo)
	for _, item := range list {
		menuList2Map[item.Id] = item
	}
	menuIds2Map := make(map[int64]int64)
	for _, id := range menuIds {
		menuIds2Map[id] = id
	}

	// 遍历menuIds, 如果每一个menuId的父id不属于menuIds的一个元素，则给menuIds追加父id
	for _, menuId := range menuIds {
		s.processMenu(menuId, menuList2Map, menuIds2Map)
	}

	menuConfigList := make([]*base.MenuConfig, 0)
	for _, mItem := range list {
		var isSelected int32
		for _, menuId := range menuIds2Map {
			if menuId == mItem.Id {
				isSelected = 1
				break
			}
		}
		perList, _ := permissionListMap[mItem.Id]
		menuConfigList = append(menuConfigList, &base.MenuConfig{
			Menu:           mItem,
			PermissionList: perList,
			IsSelected:     isSelected,
		})
	}
	return menuConfigList, nil
}

func (s *menuService) processMenu(menuId int64, menuList2Map map[int64]*menu.GfyxMenuPo, menuIds2Map map[int64]int64) {
	menuInfo, ok := menuList2Map[menuId]
	if !ok {
		return
	}

	if parentId := menuInfo.ParentId; parentId != 0 {
		if _, ok := menuIds2Map[parentId]; !ok {
			menuIds2Map[parentId] = parentId
			s.processMenu(menuInfo.ParentId, menuList2Map, menuIds2Map)
		}
	}
}
